﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using ToDoTasks.Classes;
using ToDoTasks.DataLayer;
using ToDoTasks.Services.Models;
using System.Net.Mail;
using Typesafe.Mailgun;

namespace ToDoTasks.Services.Controllers
{
    public class RecoveryController : ApiController
    {
        [HttpPost]
        [ActionName("sendEmail")]
        public HttpResponseMessage RecoveryPasswordSend([FromBody]RecoveryData data)
        {
            if (data.Username.Length < Varibles.UserNameLenght)
            {
                var respons = this.Request.CreateResponse(HttpStatusCode.BadRequest, "Username is too short");
                return respons;
            }
            if (data.NewAuthoCode.Length == Varibles.AuthCodeLenght)
            {
                var respons = this.Request.CreateResponse(HttpStatusCode.BadRequest, "AuthCode is wrong");
                return respons;
            }
            else if (data.Email == string.Empty)
            {
            }

            ToDoTasksEntities sqlcon = new ToDoTasksEntities();

            var user = GetUserBySessinKeyAndEmail(data.Username, data.Email, sqlcon);

            if (user == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "User or email are wrong");
            }

            string emailSessionKey = this.GenerateRandomKey(user.Id, Varibles.AuthCodeLenght);

            string emailContent = Varibles.PasswordChageContent + Varibles.ServerUrl +
                "api/recovery/recoveryConfirm/" + emailSessionKey;

            this.EmailSender(user.Email, Varibles.PasswordChageSubject, emailContent);

            PasswordRecovery newPass = new PasswordRecovery()
            {
                SessionKey = emailSessionKey,
                UserId = user.Id,
                NewAuthCode = data.NewAuthoCode
            };

            sqlcon.PasswordRecoveries.Add(newPass);
            sqlcon.SaveChanges();

            return this.Request.CreateResponse(HttpStatusCode.OK, "Email is send");
        }

        [HttpGet]
        [ActionName("recoveryConfirm")]
        public HttpResponseMessage RecoveryPasswordSend(string sessionKey)
        {
            ToDoTasksEntities sqlcon = new ToDoTasksEntities();

            var query =
                (from key in sqlcon.PasswordRecoveries
                 where key.SessionKey == sessionKey
                 select key).FirstOrDefault();

            if (query == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.BadRequest);
            }

            var getUser =
                (from user in sqlcon.Users
                 where user.Id == query.UserId
                 select user).FirstOrDefault();

            sqlcon.PasswordRecoveries.Remove(query);
            getUser.AuthCode = query.NewAuthCode;
            sqlcon.SaveChanges();

            return this.Request.CreateResponse(HttpStatusCode.OK);
        }

        private User GetUserBySessinKeyAndEmail(string username, string email, ToDoTasksEntities sqlcon)
        {
            var result =
                (from user in sqlcon.Users
                 where user.Username == username
                 && user.Email == email
                 select user).FirstOrDefault();

            return result;
        }

        private string GenerateRandomKey(int id, int lenght)
        {
            string symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
            StringBuilder result = new StringBuilder();
            result.Append(id);
            Random rand = new Random();

            for (int index = result.Length; index < lenght; index++)
            {
                int charIndex = rand.Next(0, symbols.Length);
                result.Append(symbols[charIndex]);
            }

            return result.ToString();
        }

        private void EmailSender(string userEmail, string subject, string content)
        {
            MailgunClient newMail = new MailgunClient(Varibles.ServerDomain, Varibles.MailApiKey);
            MailMessage newMessage = new MailMessage(Varibles.ServerEmail, userEmail, subject, content);
            newMail.SendMail(newMessage);
        }
    }
}
